﻿using System;
using System.IdentityModel.Tokens;
using System.Collections.ObjectModel;
using SecurityTokenServiceNS;
using System.Collections.Generic;
using System.IdentityModel.Claims;

namespace IssuedTokenAddIns
{
	public class IssuedTokenModuleSAML : IIssuedTokenProcessor
	{
		/// <summary>
		/// This method generates the Token to be issued
		/// </summary>
		/// <param name="stsName">Name of the Issuer</param>
		/// <param name="proof">Proof Token</param>
		/// <param name="claims">Claims</param>
		/// <param name="rstr">RSTR</param>
		public void GenerateIssuedToken(string stsName, SecurityKeyIdentifier proof, 
			Collection<Claim> claims, RSTR rstr)
		{
			if (rstr.RST.TokenType != Constants.SAML.NamespaceUri)
				return;

			Collection<SamlAttribute> samlAttributes = new Collection<SamlAttribute>();
			foreach (Claim claim in claims)
				samlAttributes.Add(new SamlAttribute(claim));

			List<string> confirmations = new List<string>(1);
			confirmations.Add(SamlConstants.HolderOfKey);

			SamlSubject samlSubject = new SamlSubject(null, null, null, confirmations, null, proof);
			SamlAttributeStatement samlAttributeStatement = new SamlAttributeStatement(samlSubject, samlAttributes);

			List<SamlStatement> samlSubjectStatements = new List<SamlStatement>();
			samlSubjectStatements.Add(samlAttributeStatement);

			SamlAssertion samlAssertion = new SamlAssertion(
				"_"+Guid.NewGuid().ToString(),
				stsName,
				DateTime.UtcNow,
				new SamlConditions(DateTime.UtcNow, DateTime.UtcNow + TimeSpan.FromHours(1)),
				new SamlAdvice(),
				samlSubjectStatements);

			X509SecurityToken issuerToken = (X509SecurityToken)StsConfiguration.Current.GetStsToken();
			//SecurityKeyIdentifier issuerKeyIdentifier = 
			//    new SecurityKeyIdentifier(issuerToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>());
			SecurityKeyIdentifier issuerKeyIdentifier =
				new SecurityKeyIdentifier(issuerToken.CreateKeyIdentifierClause<X509RawDataKeyIdentifierClause>());
			samlAssertion.SigningCredentials = new SigningCredentials(
				issuerToken.SecurityKeys[0],
                SecurityAlgorithms.RsaSha1Signature, 
				SecurityAlgorithms.Sha1Digest, 
				issuerKeyIdentifier);

			SamlSecurityToken samlToken = new SamlSecurityToken(samlAssertion);
			rstr.RequestedSecurityToken = samlToken;
			rstr.RequestedUnattachedReference = samlToken.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>();
			rstr.RequestedAttachedReference = samlToken.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>();
		}
	}
}
